<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="../assets/css/yui-cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="shortcut icon" type="image/x-icon" href="../assets/favicon.ico">
    <script src="../assets/js/yui-source.js"></script>
	<title>SoundJS v1.0.0 API Documentation : createjs/events/EventDispatcher.js</title>
</head>
<body class="yui3-skin-sam">

<div id="doc">
    <div id="hd" class="yui3-g header">
        <div class="yui3-u-3-4">
            
                <h1><a href="http://createjs.site/soundjs"><img src="../assets/docs-icon-SoundJS.png" title="SoundJS"></a></h1>
            
        </div>
        <div class="yui3-u-1-4 version">
            <em>API Documentation for: 1.0.0</em>
        </div>
    </div>
    <div id="bd" class="yui3-g">

        <div class="yui3-u-1-4">
            <div id="docs-sidebar" class="sidebar apidocs">
                <div id="api-list">
    <h2 class="off-left">APIs</h2>
    <div id="api-tabview" class="tabview">
        <ul class="tabs">
            <li><a href="#api-classes">Classes</a></li>
        </ul>

        <div id="api-tabview-filter">
            <input type="search" id="api-filter" placeholder="Type to filter APIs">
        </div>

        <div id="api-tabview-panel">
            <ul id="api-classes" class="apis classes">
            
                <li><a href="../classes/AbstractPlugin.html">AbstractPlugin</a></li>
            
                <li><a href="../classes/AbstractSoundInstance.html">AbstractSoundInstance</a></li>
            
                <li><a href="../classes/AudioSprite.html">AudioSprite</a></li>
            
                <li><a href="../classes/CordovaAudioLoader.html">CordovaAudioLoader</a></li>
            
                <li><a href="../classes/CordovaAudioPlugin.html">CordovaAudioPlugin</a></li>
            
                <li><a href="../classes/CordovaAudioSoundInstance.html">CordovaAudioSoundInstance</a></li>
            
                <li><a href="../classes/ErrorEvent.html">ErrorEvent</a></li>
            
                <li><a href="../classes/Event.html">Event</a></li>
            
                <li><a href="../classes/EventDispatcher.html">EventDispatcher</a></li>
            
                <li><a href="../classes/FlashAudioLoader.html">FlashAudioLoader</a></li>
            
                <li><a href="../classes/FlashAudioPlugin.html">FlashAudioPlugin</a></li>
            
                <li><a href="../classes/FlashAudioSoundInstance.html">FlashAudioSoundInstance</a></li>
            
                <li><a href="../classes/HTMLAudioPlugin.html">HTMLAudioPlugin</a></li>
            
                <li><a href="../classes/HTMLAudioSoundInstance.html">HTMLAudioSoundInstance</a></li>
            
                <li><a href="../classes/HTMLAudioTagPool.html">HTMLAudioTagPool</a></li>
            
                <li><a href="../classes/PlayPropsConfig.html">PlayPropsConfig</a></li>
            
                <li><a href="../classes/Sound.html">Sound</a></li>
            
                <li><a href="../classes/SoundJS.html">SoundJS</a></li>
            
                <li><a href="../classes/Utility Methods.html">Utility Methods</a></li>
            
                <li><a href="../classes/WebAudioLoader.html">WebAudioLoader</a></li>
            
                <li><a href="../classes/WebAudioPlugin.html">WebAudioPlugin</a></li>
            
                <li><a href="../classes/WebAudioSoundInstance.html">WebAudioSoundInstance</a></li>
            
            </ul>

            <ul id="api-modules" class="apis modules">
            
                <li><a href="../modules/CreateJS.html">CreateJS</a></li>
            
                <li><a href="../modules/SoundJS.html">SoundJS</a></li>
            
            </ul>
        </div>
    </div>
</div>

            </div>
        </div>
        <div class="yui3-u-3-4">
            <div id="api-options">
        Show:
        <label for="api-show-inherited">
            <input type="checkbox" id="api-show-inherited" checked>
            Inherited
        </label>

        <label for="api-show-protected">
            <input type="checkbox" id="api-show-protected">
            Protected
        </label>

        <label for="api-show-private">
            <input type="checkbox" id="api-show-private">
            Private
        </label>
        <label for="api-show-deprecated">
            <input type="checkbox" id="api-show-deprecated">
            Deprecated
        </label>

    </div>
            <div class="apidocs">
                <div id="docs-main">
                    <div class="content source-content">
                        <script>
	var name = createjs/events/EventDispatcher.js      
</script>
<h1 class="file-heading">File:EventDispatcher.js</h1>

<div class="file">
    <pre class="code prettyprint linenums">
/*
* EventDispatcher
* Visit http://createjs.site/ for documentation, updates and examples.
*
* Copyright (c) 2010 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the &quot;Software&quot;), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

/**
 * @module CreateJS
 */

// namespace:
this.createjs = this.createjs||{};

(function() {
	&quot;use strict&quot;;


// constructor:
	/**
	 * EventDispatcher provides methods for managing queues of event listeners and dispatching events.
	 *
	 * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the
	 * EventDispatcher {{#crossLink &quot;EventDispatcher/initialize&quot;}}{{/crossLink}} method.
	 * 
	 * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the
	 * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports
	 * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.
	 * 
	 * EventDispatcher also exposes a {{#crossLink &quot;EventDispatcher/on&quot;}}{{/crossLink}} method, which makes it easier
	 * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The 
	 * {{#crossLink &quot;EventDispatcher/off&quot;}}{{/crossLink}} method is merely an alias to
	 * {{#crossLink &quot;EventDispatcher/removeEventListener&quot;}}{{/crossLink}}.
	 * 
	 * Another addition to the DOM Level 2 model is the {{#crossLink &quot;EventDispatcher/removeAllEventListeners&quot;}}{{/crossLink}}
	 * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also 
	 * includes a {{#crossLink &quot;Event/remove&quot;}}{{/crossLink}} method which removes the active listener.
	 *
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 * Add EventDispatcher capabilities to the &quot;MyClass&quot; class.
	 *
	 *      EventDispatcher.initialize(MyClass.prototype);
	 *
	 * Add an event (see {{#crossLink &quot;EventDispatcher/addEventListener&quot;}}{{/crossLink}}).
	 *
	 *      instance.addEventListener(&quot;eventName&quot;, handlerMethod);
	 *      function handlerMethod(event) {
	 *          console.log(event.target + &quot; Was Clicked&quot;);
	 *      }
	 *
	 * &lt;b&gt;Maintaining proper scope&lt;/b&gt;&lt;br /&gt;
	 * Scope (ie. &quot;this&quot;) can be be a challenge with events. Using the {{#crossLink &quot;EventDispatcher/on&quot;}}{{/crossLink}}
	 * method to subscribe to events simplifies this.
	 *
	 *      instance.addEventListener(&quot;click&quot;, function(event) {
	 *          console.log(instance == this); // false, scope is ambiguous.
	 *      });
	 *      
	 *      instance.on(&quot;click&quot;, function(event) {
	 *          console.log(instance == this); // true, &quot;on&quot; uses dispatcher scope by default.
	 *      });
	 * 
	 * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage
	 * scope.
	 *
	 * &lt;b&gt;Browser support&lt;/b&gt;
	 * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model
	 * requires modern browsers (IE9+).
	 *      
	 *
	 * @class EventDispatcher
	 * @constructor
	 **/
	function EventDispatcher() {
	
	
	// private properties:
		/**
		 * @protected
		 * @property _listeners
		 * @type Object
		 **/
		this._listeners = null;
		
		/**
		 * @protected
		 * @property _captureListeners
		 * @type Object
		 **/
		this._captureListeners = null;
	}
	var p = EventDispatcher.prototype;

// static public methods:
	/**
	 * Static initializer to mix EventDispatcher methods into a target object or prototype.
	 * 
	 * 		EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class
	 * 		EventDispatcher.initialize(myObject); // add to a specific instance
	 * 
	 * @method initialize
	 * @static
	 * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a
	 * prototype.
	 **/
	EventDispatcher.initialize = function(target) {
		target.addEventListener = p.addEventListener;
		target.on = p.on;
		target.removeEventListener = target.off =  p.removeEventListener;
		target.removeAllEventListeners = p.removeAllEventListeners;
		target.hasEventListener = p.hasEventListener;
		target.dispatchEvent = p.dispatchEvent;
		target._dispatchEvent = p._dispatchEvent;
		target.willTrigger = p.willTrigger;
	};
	

// public methods:
	/**
	 * Adds the specified event listener. Note that adding multiple listeners to the same function will result in
	 * multiple callbacks getting fired.
	 *
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 *
	 *      displayObject.addEventListener(&quot;click&quot;, handleClick);
	 *      function handleClick(event) {
	 *         // Click happened.
	 *      }
	 *
	 * @method addEventListener
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
	 * the event is dispatched.
	 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
	 * @return {Function | Object} Returns the listener for chaining or assignment.
	 **/
	p.addEventListener = function(type, listener, useCapture) {
		var listeners;
		if (useCapture) {
			listeners = this._captureListeners = this._captureListeners||{};
		} else {
			listeners = this._listeners = this._listeners||{};
		}
		var arr = listeners[type];
		if (arr) { this.removeEventListener(type, listener, useCapture); }
		arr = listeners[type]; // remove may have deleted the array
		if (!arr) { listeners[type] = [listener];  }
		else { arr.push(listener); }
		return listener;
	};
	
	/**
	 * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener
	 * only run once, associate arbitrary data with the listener, and remove the listener.
	 * 
	 * This method works by creating an anonymous wrapper function and subscribing it with addEventListener.
	 * The wrapper function is returned for use with &#x60;removeEventListener&#x60; (or &#x60;off&#x60;).
	 * 
	 * &lt;b&gt;IMPORTANT:&lt;/b&gt; To remove a listener added with &#x60;on&#x60;, you must pass in the returned wrapper function as the listener, or use
	 * {{#crossLink &quot;Event/remove&quot;}}{{/crossLink}}. Likewise, each time you call &#x60;on&#x60; a NEW wrapper function is subscribed, so multiple calls
	 * to &#x60;on&#x60; with the same params will create multiple listeners.
	 * 
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 * 
	 * 		var listener = myBtn.on(&quot;click&quot;, handleClick, null, false, {count:3});
	 * 		function handleClick(evt, data) {
	 * 			data.count -= 1;
	 * 			console.log(this == myBtn); // true - scope defaults to the dispatcher
	 * 			if (data.count == 0) {
	 * 				alert(&quot;clicked 3 times!&quot;);
	 * 				myBtn.off(&quot;click&quot;, listener);
	 * 				// alternately: evt.remove();
	 * 			}
	 * 		}
	 * 
	 * @method on
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
	 * the event is dispatched.
	 * @param {Object} [scope] The scope to execute the listener in. Defaults to the dispatcher/currentTarget for function listeners, and to the listener itself for object listeners (ie. using handleEvent).
	 * @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.
	 * @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called.
	 * @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
	 * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.
	 **/
	p.on = function(type, listener, scope, once, data, useCapture) {
		if (listener.handleEvent) {
			scope = scope||listener;
			listener = listener.handleEvent;
		}
		scope = scope||this;
		return this.addEventListener(type, function(evt) {
				listener.call(scope, evt, data);
				once&amp;&amp;evt.remove();
			}, useCapture);
	};

	/**
	 * Removes the specified event listener.
	 *
	 * &lt;b&gt;Important Note:&lt;/b&gt; that you must pass the exact function reference used when the event was added. If a proxy
	 * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or
	 * closure will not work.
	 *
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 *
	 *      displayObject.removeEventListener(&quot;click&quot;, handleClick);
	 *
	 * @method removeEventListener
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener The listener function or object.
	 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
	 **/
	p.removeEventListener = function(type, listener, useCapture) {
		var listeners = useCapture ? this._captureListeners : this._listeners;
		if (!listeners) { return; }
		var arr = listeners[type];
		if (!arr) { return; }
		for (var i=0,l=arr.length; i&lt;l; i++) {
			if (arr[i] == listener) {
				if (l==1) { delete(listeners[type]); } // allows for faster checks.
				else { arr.splice(i,1); }
				break;
			}
		}
	};
	
	/**
	 * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the
	 * .on method.
	 * 
	 * &lt;b&gt;IMPORTANT:&lt;/b&gt; To remove a listener added with &#x60;on&#x60;, you must pass in the returned wrapper function as the listener. See 
	 * {{#crossLink &quot;EventDispatcher/on&quot;}}{{/crossLink}} for an example.
	 *
	 * @method off
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener The listener function or object.
	 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
	 **/
	p.off = p.removeEventListener;

	/**
	 * Removes all listeners for the specified type, or all listeners of all types.
	 *
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 *
	 *      // Remove all listeners
	 *      displayObject.removeAllEventListeners();
	 *
	 *      // Remove all click listeners
	 *      displayObject.removeAllEventListeners(&quot;click&quot;);
	 *
	 * @method removeAllEventListeners
	 * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed.
	 **/
	p.removeAllEventListeners = function(type) {
		if (!type) { this._listeners = this._captureListeners = null; }
		else {
			if (this._listeners) { delete(this._listeners[type]); }
			if (this._captureListeners) { delete(this._captureListeners[type]); }
		}
	};

	/**
	 * Dispatches the specified event to all listeners.
	 *
	 * &lt;h4&gt;Example&lt;/h4&gt;
	 *
	 *      // Use a string event
	 *      this.dispatchEvent(&quot;complete&quot;);
	 *
	 *      // Use an Event instance
	 *      var event = new createjs.Event(&quot;progress&quot;);
	 *      this.dispatchEvent(event);
	 *
	 * @method dispatchEvent
	 * @param {Object | String | Event} eventObj An object with a &quot;type&quot; property, or a string type.
	 * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,
	 * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can
	 * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.
	 * @param {Boolean} [bubbles] Specifies the &#x60;bubbles&#x60; value when a string was passed to eventObj.
	 * @param {Boolean} [cancelable] Specifies the &#x60;cancelable&#x60; value when a string was passed to eventObj.
	 * @return {Boolean} Returns false if &#x60;preventDefault()&#x60; was called on a cancelable event, true otherwise.
	 **/
	p.dispatchEvent = function(eventObj, bubbles, cancelable) {
		if (typeof eventObj == &quot;string&quot;) {
			// skip everything if there&#x27;s no listeners and it doesn&#x27;t bubble:
			var listeners = this._listeners;
			if (!bubbles &amp;&amp; (!listeners || !listeners[eventObj])) { return true; }
			eventObj = new createjs.Event(eventObj, bubbles, cancelable);
		} else if (eventObj.target &amp;&amp; eventObj.clone) {
			// redispatching an active event object, so clone it:
			eventObj = eventObj.clone();
		}
		
		// TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent
		try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events

		if (!eventObj.bubbles || !this.parent) {
			this._dispatchEvent(eventObj, 2);
		} else {
			var top=this, list=[top];
			while (top.parent) { list.push(top = top.parent); }
			var i, l=list.length;

			// capture &amp; atTarget
			for (i=l-1; i&gt;=0 &amp;&amp; !eventObj.propagationStopped; i--) {
				list[i]._dispatchEvent(eventObj, 1+(i==0));
			}
			// bubbling
			for (i=1; i&lt;l &amp;&amp; !eventObj.propagationStopped; i++) {
				list[i]._dispatchEvent(eventObj, 3);
			}
		}
		return !eventObj.defaultPrevented;
	};

	/**
	 * Indicates whether there is at least one listener for the specified event type.
	 * @method hasEventListener
	 * @param {String} type The string type of the event.
	 * @return {Boolean} Returns true if there is at least one listener for the specified event.
	 **/
	p.hasEventListener = function(type) {
		var listeners = this._listeners, captureListeners = this._captureListeners;
		return !!((listeners &amp;&amp; listeners[type]) || (captureListeners &amp;&amp; captureListeners[type]));
	};
	
	/**
	 * Indicates whether there is at least one listener for the specified event type on this object or any of its
	 * ancestors (parent, parent&#x27;s parent, etc). A return value of true indicates that if a bubbling event of the
	 * specified type is dispatched from this object, it will trigger at least one listener.
	 * 
	 * This is similar to {{#crossLink &quot;EventDispatcher/hasEventListener&quot;}}{{/crossLink}}, but it searches the entire
	 * event flow for a listener, not just this object.
	 * @method willTrigger
	 * @param {String} type The string type of the event.
	 * @return {Boolean} Returns &#x60;true&#x60; if there is at least one listener for the specified event.
	 **/
	p.willTrigger = function(type) {
		var o = this;
		while (o) {
			if (o.hasEventListener(type)) { return true; }
			o = o.parent;
		}
		return false;
	};

	/**
	 * @method toString
	 * @return {String} a string representation of the instance.
	 **/
	p.toString = function() {
		return &quot;[EventDispatcher]&quot;;
	};


// private methods:
	/**
	 * @method _dispatchEvent
	 * @param {Object | Event} eventObj
	 * @param {Object} eventPhase
	 * @protected
	 **/
	p._dispatchEvent = function(eventObj, eventPhase) {
		var l, arr, listeners = (eventPhase &lt;= 2) ? this._captureListeners : this._listeners;
		if (eventObj &amp;&amp; listeners &amp;&amp; (arr = listeners[eventObj.type]) &amp;&amp; (l=arr.length)) {
			try { eventObj.currentTarget = this; } catch (e) {}
			try { eventObj.eventPhase = eventPhase|0; } catch (e) {}
			eventObj.removed = false;
			
			arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch
			for (var i=0; i&lt;l &amp;&amp; !eventObj.immediatePropagationStopped; i++) {
				var o = arr[i];
				if (o.handleEvent) { o.handleEvent(eventObj); }
				else { o(eventObj); }
				if (eventObj.removed) {
					this.off(eventObj.type, o, eventPhase==1);
					eventObj.removed = false;
				}
			}
		}
		if (eventPhase === 2) { this._dispatchEvent(eventObj, 2.1); }
	};


	createjs.EventDispatcher = EventDispatcher;
}());

    </pre>
</div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>
